package com.sylli.oeuf.server.db.sql;

import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;

import com.sylli.oeuf.server.exception.BasedException;
import com.sylli.oeuf.server.exception.ExceptionCause;
import com.sylli.oeuf.server.object.transferable.BasedTO;
import com.sylli.oeuf.server.object.transferable.CharacterGeneralInfoTO;
import com.sylli.oeuf.server.object.transferable.LevelUpTO;
import com.sylli.oeuf.server.object.transferable.SkillBundleTO;
import com.sylli.oeuf.server.object.transferable.StatTO;
import com.sylli.oeuf.server.object.transferable.StrategyBundleTO;

public class MySQLCharacterGeneralInfoProvider extends MySQLBasedProvider<CharacterGeneralInfoTO> {
	
	public MySQLCharacterGeneralInfoProvider() {
		interactTableName = "character_general_info";
	}
	
//	public MySQLCharacterGeneralInfoProvider(DatabaseCache<CharacterGeneralInfoTO> cache) {
//		super(cache);
//		interactTableName = "character_general_info";
//	}

	@Override
	protected PreparedStatement convertObjectToInsertQuery(CharacterGeneralInfoTO obj) throws BasedException {
		try {
			PreparedStatement ps = mysqlConnector.getConnectionObject().prepareStatement(
					"INSERT INTO " + interactTableName 
					+ " (account_id, name, class, stat, max_hp, max_mp, level, max_exp, strategy, levelup, skills)"
					+ " VALUES (?,?,?,?,?,?,?,?,?)", 
					Statement.RETURN_GENERATED_KEYS);
			ps.setInt(1, obj.getAccountId());
			ps.setString(2, obj.getName());
			ps.setInt(3, obj.getClazzId());
			ps.setBytes(4, obj.getStat().toBytes());
			ps.setInt(5, obj.getMaxHp());
			ps.setInt(6, obj.getMaxMp());
			ps.setInt(7, obj.getLevel());
			ps.setInt(8, obj.getMaxExp());
			ps.setBytes(9, obj.getStrategyBundle().toBytes());
			ps.setBytes(10, obj.getLevelUp().toBytes());
			ps.setBytes(11, obj.getSkillBundle().toBytes());
			return ps;
		} catch (SQLException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryCreationFail, e);
		} catch (IOException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryCreationFail, "Conversion to byte[]", e);
		}
	}

	@Override
	protected PreparedStatement convertObjectToUpdateQuery(CharacterGeneralInfoTO obj) throws BasedException {
		try {
			PreparedStatement ps = mysqlConnector.getConnectionObject().prepareStatement(
					"UPDATE " + interactTableName 
					+ " SET account_id=?, name=?, class=?, stat=?, max_hp=?, max_mp=?, level=?, max_exp=?, strategy=?, levelup=?, skills=? WHERE char_id = ?;");
			ps.setInt(1, obj.getAccountId());
			ps.setString(2, obj.getName());
			ps.setInt(3, obj.getClazzId());
			ps.setBytes(4, obj.getStat().toBytes());
			ps.setInt(5, obj.getMaxHp());
			ps.setInt(6, obj.getMaxMp());
			ps.setInt(7, obj.getLevel());
			ps.setInt(8, obj.getMaxExp());
			ps.setBytes(9, obj.getStrategyBundle().toBytes());
			ps.setBytes(10, obj.getLevelUp().toBytes());
			ps.setBytes(11, obj.getSkillBundle().toBytes());
			ps.setInt(12, obj.getCharId());
			return ps;
		} catch (SQLException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryUpdateFail, e);
		} catch (IOException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryUpdateFail, "Conversion to byte[]", e);
		}
	}

	@Override
	protected CharacterGeneralInfoTO convertResultSetToObject(ResultSet rs) throws BasedException {
		try {
			CharacterGeneralInfoTO sto = new CharacterGeneralInfoTO();
			rs.first();
			sto.setCharId(rs.getInt(1));
			sto.setAccountId(rs.getInt(2));
			sto.setName(rs.getString(3));
			sto.setClazzId(rs.getInt(4));
			sto.setStat((StatTO) BasedTO.fromBytes(rs.getBytes(5)));
			sto.setMaxHp(rs.getInt(6));
			sto.setMaxMp(rs.getInt(7));
			sto.setLevel(rs.getInt(8));
			sto.setMaxExp(rs.getInt(9));
			byte[] obj = rs.getBytes(10);
			if (obj == null) {
				sto.setStrategyBundle(new StrategyBundleTO());
			} else {
				sto.setStrategyBundle((StrategyBundleTO) BasedTO.fromBytes(obj));
			}
			byte[] buf = rs.getBytes(12);
			if (buf == null) {
				sto.setLevelUp(new LevelUpTO());
			} else {
				sto.setLevelUp((LevelUpTO) BasedTO.fromBytes(buf));
			}
			byte[] buf2 = rs.getBytes(13);
			if (buf2 == null) {
				sto.setSkillBundle(new SkillBundleTO());
			} else {
				sto.setSkillBundle((SkillBundleTO) BasedTO.fromBytes(buf2));
			}
			return sto;
		} catch (SQLException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryAccessingFail, e);
		} catch (IOException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryAccessingFail, "Conversion from byte[]", e);
		} catch (ClassNotFoundException e) {
			throw new BasedException(ExceptionCause.DatabaseEntryAccessingFail, "Conversion from byte[]", e);
		}
	}

	@Override
	protected Collection<CharacterGeneralInfoTO> convertResultSetToObjects(ResultSet rs) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected PreparedStatement convertObjectToInsertQuery(Collection<CharacterGeneralInfoTO> objs) {
		// TODO Auto-generated method stub
		return null;
	}
}
